#ifndef WEBCLIENT_HPP
#define WEBCLIENT_HPP

/*!
  \file web_client.hpp
*/

/****************************************************
*       Forward declaration
****************************************************/
class QIODevice;
class QStringList;
class QBuffer;
class QEventLoop;
template <class Key, class T>
class QMap;
//class QNetworkReply;

/****************************************************
*       QT dependencies
****************************************************/
#include <QString>
#include <QNetworkAccessManager>
#include <QNetworkReply>

/****************************************************
*       WebClient class declatation
****************************************************/

/*!
  \class WebClient
  \brief Class used to access web pages.

  Class that provides a direct interface to HTTP services.
*/
class WebClient : public QNetworkAccessManager
{
    Q_OBJECT;
public:
    enum SynchronizationMode {
        Asynchronous,
        Synchronous
    };
private:
    struct Request
    {
        QString url;
    //    QNetworkReply::NetworkError status;
        int status;
        QIODevice *buffer;
    };

    QEventLoop *_eventLoop;

    QMap<QString, Request> *_connections;

    int _makeRequest(Operation operation, QString _url, QString args, QIODevice* to);

    void _registerRequest(QString url, QIODevice *buffer);

    void _init(SynchronizationMode mode);


public:
    SynchronizationMode synchronizationMode;

    /*!
    * \brief Constructor
    *
    * \param mode Specify if WebClient is used Synchronously/Asynchronously
    */
    WebClient(SynchronizationMode mode=Asynchronous, QObject* parent=0);

    /*!
    * \brief Destructor
    */
    virtual ~WebClient();

    /*!
    * \brief HTTP GET method on an URL
    *
    * Function used to perform a HTTP GET method on a given URL
    *
    * \param  url URL to perform the GET method on
    * \param  to Where to store fetched data. If NULL then fetched data
    * is returned by the method
    * \return in Synchonous mode return the status of the request. In asynchronous
    *         mode return the request Id
    */
    int get(QString url, QIODevice* to);

    /*!
    * \brief HTTP POST method on an URL
    *
    * Function used to perform a HTTP GET method on a given URL
    *
    * \param  url URL to perform the GET method on
    * \param  args Params that are associated to the HTTP POST method
    * \param  to Where to store fetched data. Can be a file or a memory stream
    * \return in Synchonous mode return the status of the request. In asynchronous
    *         mode return the request Id
    */
    int post(QString url, QMap<QString, QString> args, QIODevice* to);

    int post(QString url, QStringList args, QIODevice* to);

signals:
    /*!
    * \brief Signal emited when GET/POST request is finished.
    *
    * \param  requestId Id of the finished request
    * \param  status Status of the finished request
    * \param  data Buffer associated to the request
    */
    void httpRequestFinished(QString url, int status, QIODevice* data);

private slots:
    void _replyFinished(QNetworkReply* reply);
public:
    enum WebClientError {
        NoError = QNetworkReply::NoError,
    };
};

#endif // WEBCLIENT_HPP
